Skip to content

modules: mcuboot: enable support for RAMLOAD mode with revert #85254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

danieldegrasse
Copy link
Contributor

@danieldegrasse danieldegrasse commented Feb 5, 2025

This PR adds support for RAMLOAD mode with revert in MCUBoot, and enables a testcase for it with the mcumgr subsystem. RAMLOAD mode with revert functions similar to the direct xip mode with revert- MCUBoot will not ramload an image that is not confirmed or marked pending.

This PR also modifies the method of getting the active slot number when using ramload modes- we need to query the flash area ID, not the active boot slot for use with mcuboot boot utilities

@zephyrbot
Copy link

zephyrbot commented Feb 5, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
mcuboot mcu-tools/mcuboot@07222c1 mcu-tools/mcuboot#2197 mcu-tools/mcuboot#2197/files

Additional metadata changed:

Name URL Submodules West cmds module.yml Blobs
mcuboot

DNM label due to: 1 project with PR revision and 1 project with metadata changes

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@zephyrbot zephyrbot added manifest manifest-mcuboot DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Feb 5, 2025
@danieldegrasse
Copy link
Contributor Author

Note: this PR requires mcu-tools/mcuboot#2197 from MCUBoot. It also contains commits from #85096, because I validated this support on the RT1050-EVK

@nordicjm
Copy link
Contributor

nordicjm commented Apr 15, 2025

Build and flash, use a program to upload the secondary image without changing version (not jlink, upload using MCUmgr), mark it as test/confirmed, reboot, device state is stuck

@danieldegrasse
Copy link
Contributor Author

Build and flash, use a program to upload the secondary image without changing version (not jlink, upload using MCUmgr), mark it as test/confirmed, reboot, device state is stuck

Really not sure what I'm missing, but I still don't see an issue. These are the build commands I'm running, after erasing the flash of the RT1050:

$ west build -p always -b mimxrt1050_evk/mimxrt1052/hyperflash -T samples/subsys/mgmt/mcumgr/smp_svr/sample.mcumgr.smp_svr.ram_load_revert.serial -- -DCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION=\"0.0.0+0\"
$ west flash -r jlink
# Rebuild so the image sha will actually be different (otherwise the image cannot be marked for test)
$ west build -p always -b mimxrt1050_evk/mimxrt1052/hyperflash -T samples/subsys/mgmt/mcumgr/smp_svr/sample.mcumgr.smp_svr.ram_load_revert.serial -- -DCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION=\"0.0.0+0\"
# Upload new image
$ ../../mcumgr-client/target/release/mcumgr-client -d /dev/ttyACM0 upload build/smp_svr/zephyr/zephyr.signed.bin
# Mark image for test
$ ../../mcumgr-client/target/release/mcumgr-client -d /dev/ttyACM0 test 69732fb7b5dbcf0b9c7f3c62ad073894b631093d2045fa9b36204b0b6c50432e
# Reset board, first slot image still boots (since version numbers are equivalent)
# Build new image with updated version
$  west build -p always -b mimxrt1050_evk/mimxrt1052/hyperflash -T samples/subsys/mgmt/mcumgr/smp_svr/sample.mcumgr.smp_svr.ram_load_revert.serial -- -DCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION=\"0.0.1+0\"
$ ../../mcumgr-client/target/release/mcumgr-client -d /dev/ttyACM0 upload build/smp_svr/zephyr/zephyr.signed.bin
# Mark new image for test
$ ../../mcumgr-client/target/release/mcumgr-client -d /dev/ttyACM0 test 8c21e43c3a1ef4d9b5aca59da6ec79a6bd18c078de8a006d49326082d540828f
# Reset board, verify new image is running
# Reset board again, verify that the image is removed from flash as it did not confirm itself

This all seems functional to me. Do these steps not work for you? Or is the concern that the new image with the same version number does not run? I think that is expected behavior- the only way to indicate which image mcuboot should select to run with this feature is via the version number

@danieldegrasse danieldegrasse force-pushed the feature/mcuboot-ramload-revert branch 2 times, most recently from b843167 to e0e4181 Compare April 25, 2025 22:36
@danieldegrasse
Copy link
Contributor Author

This all seems functional to me. Do these steps not work for you? Or is the concern that the new image with the same version number does not run? I think that is expected behavior- the only way to indicate which image mcuboot should select to run with this feature is via the version number

@nordicjm ping- I would like to get this feature functional on your hardware, but I still don't understand what test case you are running that fails

@nordicjm
Copy link
Contributor

Build sample with CONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING=n, flash to device, then without changing any Kconfigs or anything or rebuilding just upload the slot1 image using MCUmgr with any supported tool from file zephyr.slot1.signed.confirmed.bin and reboot - at this point the device will boot from slot 0 not slot 1 as it should according to the flags, then try uploading an image or erasing the slot using MCUmgr, you will get an error that there is no free slot to place the image, and your device is "bricked" because you can no longer load a firmware update to it (without erasing the flash with a debugger, that is)

@danieldegrasse
Copy link
Contributor Author

danieldegrasse commented Jun 24, 2025

Build sample with CONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING=n, flash to device, then without changing any Kconfigs or anything or rebuilding just upload the slot1 image using MCUmgr with any supported tool from file zephyr.slot1.signed.confirmed.bin and reboot - at this point the device will boot from slot 0 not slot 1 as it should according to the flags, then try uploading an image or erasing the slot using MCUmgr, you will get an error that there is no free slot to place the image, and your device is "bricked" because you can no longer load a firmware update to it (without erasing the flash with a debugger, that is)

Ahh ok- now this makes sense, thank you- I've made the following change in this push, should fix it:

diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
index 5333d651c9f..1860269d87f 100644
--- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
+++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
@@ -332,7 +332,8 @@ img_mgmt_slot_in_use(int slot)
        int active_slot = img_mgmt_active_slot(image);

 #if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \
-       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
+       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) && \
+       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT)
        enum img_mgmt_next_boot_type type = NEXT_BOOT_TYPE_NORMAL;
        int nbs = img_mgmt_get_next_boot_slot(image, &type);

I believe we just want to always allow erasing a pending/confirmed image if it is inactive- otherwise the user can flash two images that are both confirmed, and effectively brick their device

@danieldegrasse danieldegrasse force-pushed the feature/mcuboot-ramload-revert branch from e0e4181 to 6bc9089 Compare June 24, 2025 22:12
MCUMgr ram load support was hardcoding the overlay file for the
nrf52840dk. To make this support generic, move the _ram_load overlay
file to the MCUBoot repository, as part of the mcuboot application.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
MCUBoot RAMLOAD mode relies on CONFIG_XIP=n, but FLASH_MCUX_FLEXSPI_XIP
y-selects this symbol. Disable CONFIG_FLASH_MCUX_FLEXSPI_XIP for the
case where we are using MCUBoot ramload mode.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Add support for using the ramload mode of MCUBoot on the mimxrt1050_evk

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Add Kconfigs for RAMLOAD_WITH_REVERT mode in MCUBoot. This mode works in
a manner similar to DIRECT_XIP_WITH_REVERT- namely, mcuboot will only
boot an image that is either confirmed or marked as pending. If both
images are confirmed, mcuboot will still select the one with the higher
version, so downgrading is not possible using this mode.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Add BOOT_RAM_LOAD_REVERT as a defined Kconfig to the whitelist

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
When signing for ramload mode, respect the write alignment size setting.
This is required when creating a confirmed image, as the BOOT_MAGIC
value changes based on the alignment size in use.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Prefer flashing the confirmed image when one is created with
CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE. This way, the west runner will
flash this image over the signed image if it exists.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
…cies

CONFIG_FLASH_MCUX_FLEXSPI_XIP should also be disabled when using MCUBoot
ramload mode with revert support.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Much like in RAMLOAD mode, RAMLOAD_WITH_REVERT requires that mcuboot
subsystem fetch bootloader information via the retention subsystem.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Update mcuboot revision to include ramload support. This commit can be
dropped once ramload support is present within Zephyr's revision of
MCUBoot.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
@danieldegrasse danieldegrasse force-pushed the feature/mcuboot-ramload-revert branch from 6bc9089 to aa6490d Compare June 27, 2025 15:45
Comment on lines +116 to +119
case 1:
fa_id = FIXED_PARTITION_ID(SLOT1_PARTITION);
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs #if here too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added- thanks. What will we need to do on the MCUBoot side to synchronize this? I think this change will have to go in when we update MCUBoot to include mcu-tools/mcuboot#2197 since we are moving the overlays as well

@nordicjm
Copy link
Contributor

Build sample with CONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING=n, flash to device, then without changing any Kconfigs or anything or rebuilding just upload the slot1 image using MCUmgr with any supported tool from file zephyr.slot1.signed.confirmed.bin and reboot - at this point the device will boot from slot 0 not slot 1 as it should according to the flags, then try uploading an image or erasing the slot using MCUmgr, you will get an error that there is no free slot to place the image, and your device is "bricked" because you can no longer load a firmware update to it (without erasing the flash with a debugger, that is)

Ahh ok- now this makes sense, thank you- I've made the following change in this push, should fix it:

diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
index 5333d651c9f..1860269d87f 100644
--- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
+++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c
@@ -332,7 +332,8 @@ img_mgmt_slot_in_use(int slot)
        int active_slot = img_mgmt_active_slot(image);

 #if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \
-       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
+       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) && \
+       !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT)
        enum img_mgmt_next_boot_type type = NEXT_BOOT_TYPE_NORMAL;
        int nbs = img_mgmt_get_next_boot_slot(image, &type);

I believe we just want to always allow erasing a pending/confirmed image if it is inactive- otherwise the user can flash two images that are both confirmed, and effectively brick their device

Great, is working now! One outstanding issue then looks good

boot_fetch_active_slot needs to map the slot number to a flash ID, as
this is what the DFU subsystem expects when interacting with the flash
partition.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
We should not block erasing pending images when using ramload with
revert mode, because uploading multiple confirmed images with the same
version would brick the device (preventing future FW updates). Update
the dependencies of img_mgmt_slot_in_use to account for this.

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
Add testcase to build mcuboot and smp_svr application using ramload
with revert mode

Signed-off-by: Daniel DeGrasse <ddegrasse@tenstorrent.com>
@danieldegrasse danieldegrasse force-pushed the feature/mcuboot-ramload-revert branch from aa6490d to 0c5ec1d Compare July 1, 2025 15:28
Copy link

sonarqubecloud bot commented Jul 1, 2025

Copy link
Contributor

@d3zd3z d3zd3z left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good. Once mcuboot has moved to a supporting version, I can give an approval.

@@ -23,6 +23,8 @@ manifest:
url-base: https://github.com/zephyrproject-rtos
- name: babblesim
url-base: https://github.com/BabbleSim
- name: mcuboot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have merged 2197 into mcuboot, so once this makes it into the Zephyr module, we can directly refer to that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great- I think we will need to be careful with synchronization here- the MCUBoot side change moves some overlay files into the MCUBoot repo that were previously defined here (used for the ramload sample). So I think that these changes (or a subset) will be needed with the PR that bumps the mcuboot manifest revision.

from there. The image must be linked to execute from RAM, the address that it is copied
to is specified using the load-addr argument when running imgtool.
This option automatically selectes MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible
to swap back to older version of the application.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little ambiguous to me, since the revert does kind of go back to an older version of the application. Not sure how to word it more clearly, though.

Copy link
Contributor Author

@danieldegrasse danieldegrasse Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is true. Perhaps

This option automatically selectes MCUBOOT_BOOTLOADER_NO_DOWNGRADE as MCUBoot will automatically select the highest revision of the application to boot. Note however that MCUBoot will select an older revision of the application if the booted revision does not mark itself as confirmed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants